package org.javia.arity;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.*;

public class SymbolsTest {

	Symbols symbols;
	@Before
	public void setUp() throws Exception {
		symbols= new Symbols();
	}

	@After
	public void tearDown() throws Exception {
		
	}



	@Test
	public void testIsDefinition() {
		assertTrue(symbols.isDefinition("a=2+2"));
		assertFalse(symbols.isDefinition("2+2"));
		
	}

	@Test
	public void testEval() throws SyntaxException {
		assertEquals(4,symbols.eval("2+2"),0.0001);
	}

	@Test
	public void testEvalComplex() throws SyntaxException {
		assertEquals(new Complex(8,0),symbols.evalComplex("4+4"));
	}

	@Test
	public void testCompileWithName() throws SyntaxException {
	FunctionAndName fn=symbols.compileWithName("2+2x");
	Function fn2=fn.function;
	assertEquals(4,fn2.eval(1),0.0001);
	assertEquals(6,fn2.eval(2),0.0001);
	assertEquals(8,fn2.eval(3),0.0001);
	
	}

	@Test
	public void testCompile() throws SyntaxException {
	Function fn=symbols.compile("2+2");
	assertEquals(4,fn.eval(),0.0001);
	}

	@Test
	public void testDefineStringFunction() throws SyntaxException {
		Function f=symbols.compile("2+2");
	  symbols.define("function", f);
	}

//	@Test
//	public void testDefineFunctionAndName() {
//		fail("Not yet implemented");
//	}
//
//	@Test
//	public void testDefineStringDouble() {
//		fail("Not yet implemented");
//	}

	@Test
	public void testDefineStringComplex() {
	Complex c=	mock(Complex.class);
	c.im=0;
	c.re=1;
		symbols.define("complex", c);
		Symbol s=symbols.lookupConst("complex");
		assertFalse(s.isConst);
		assertFalse(s.isEmpty());
		assertEquals(1,s.valueRe,0.0001);
		assertEquals(0,s.valueIm,0.0001);
		
	}

	@Test
	public void testPushAndPopFrame() {
		Complex c=	mock(Complex.class);
		c.im=0;
		c.re=1;
		symbols.pushFrame();
		symbols.define("complex", c);
		symbols.popFrame();
		Symbol poped=symbols.lookupConst("complex");
		assertNull(poped);
			
	}


	@Test
	public void testGetTopFrame() {
		Complex c=	mock(Complex.class);
		c.im=0;
		c.re=1;
		symbols.pushFrame();
		symbols.define("complex", c);
		Symbol[] s=symbols.getTopFrame();
		assertEquals(1,s.length);
		
		symbols=new Symbols();
		symbols.pushFrame();
		Symbol[] s2=symbols.getTopFrame();
		assertEquals(0,s2.length);
		
	}

	@Test
	public void testGetAllSymbols() {
			Complex c=	mock(Complex.class);
			
			c.im=0;
			c.re=1;
			symbols.define("complex", c);
			Symbol[] s=symbols.getAllSymbols();
			assertEquals(65,s.length); //64 default +1
	}

	@Test
	public void testGetDictionary() {
		Complex c=	mock(Complex.class);
		
		c.im=0;
		c.re=1;
		symbols.define("complex", c);
		String[] s=symbols.getDictionary();
		assertEquals(65,s.length);
		assertEquals("complex",s[s.length-1]);
	}

	
	

}
